-- zs5/MyFix.hs
fix :: (a -> a) -> a
fix f = f (fix f)

factorial :: Int -> Int

f = (\f1 n -> if (n == 0) then 1 else n * f1 (n - 1))

factorial = fix f

{-
f1:: Int->Int

fix f: 递归嵌入自己
f:: f1->f1': 递归修饰自己

factorial 3 = fix (f) 3
= f (fix f) 3
= 3* (fix f 2)
= 3* (f (fix f) 2)
-}

-- 第一个参数永远是 函数
f2 f1 a b
  | a == 0 = [(0, b)]
  | b == 0 = [(a, 0)]
  | otherwise = (a, b) : f1 (a - 1) (b - 1)

nest = fix f2

-- ====================================
-- Newton.hs
squareroot :: Int -> Double -> Double
squareroot 0 x = x
squareroot n x = (s + x / s) / 2
  where
    s = squareroot (n - 1) x

ret = squareroot 10 5

-- +++++++++++++++++++++++++++++++++++++

fix2 :: (t -> t -> Bool) -> (t -> t) -> t -> t
fix2 c f x
  | c x (f x) = x
  | otherwise = fix2 c f (f x)

newton :: (Fractional a) => a -> a -> a
newton c t = (c / t + t) / 2.0

mysqrt :: Double -> Double
mysqrt c = fix2 (\a b -> a - b < 0.000001) (newton c) c

ret2 = mysqrt 3
